package com.fpt.group3.controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fpt.group3.service.CountryServiceImpl;
import com.fpt.group3.service.TrustRegionServiceImpl;
import com.fpt.group3.service.exception.SystemException;
import com.fpt.group3.form.TrustRegion;
import com.fpt.group3.form.Country;

/**
 * Handles requests for the application home page.
 */
@Controller
public class TrustRegionController {
    /**
     * logger to log some value in debug.
     */
    private static final Logger LOGGER = LoggerFactory
            .getLogger(TrustRegionController.class);
    /**
     * this variable to save trust region in temp.
     */
    private TrustRegion trustRegion;
    /**
     * this variable to save process update or not.
     */
    private boolean isUpdate = false;

    /**
     * mapping with first page.
     * @param model mode to pass value to views
     * @return String
     * @throws IOException throws IO exception
     * @throws SystemException throws system exception
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public final String homePage(final Model model) throws IOException,
       SystemException {
        LOGGER.info("Access home Page");
        return "Homepage";
    }

    /**
     * mapping with first page.
     * @param model mode to pass value to views
     * @return String
     * @throws IOException throws IO exception
     * @throws SystemException throws system exception
     */
    @RequestMapping(value = "/ListTrustRegion", method = RequestMethod.GET)
    public final String trustRegion(final Model model) throws IOException,
       SystemException {
        LOGGER.info("access TrustRegion Page");
        ApplicationContext context = new ClassPathXmlApplicationContext(
            new String[] {"Spring-Module.xml"});
        TrustRegionServiceImpl trService = context.getBean(
            "trustRegionServiceImpl", TrustRegionServiceImpl.class);

        //pass false for all region
        List<TrustRegion> listRegion = trService.listTrustRegion(false);
        model.addAttribute("listRegion", listRegion);
    return "ListTrustRegion";
    }

    /**
     * pass data to trustRegionDetail.
     * @param model store data to pass
     * @return string
     * @throws IOException throw exception
     * @throws SystemException throw exception
     */
    @RequestMapping(value = "/TrustRegionDetail", method = RequestMethod.GET)
    public final String trustRegionDetail(final Model model)
            throws IOException, SystemException {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] {"Spring-Module.xml"});
        CountryServiceImpl coService = context.getBean("countryServiceImpl",
                CountryServiceImpl.class);
        List<Country> listCountry = coService.listCountry();
        model.addAttribute("listCountry", listCountry);

        //pass Yes for have In-active
        model.addAttribute("inActiveBtn", "Yes");
                                                    // button
        // set isUpdate == true to update region later
        this.isUpdate = true;
        LOGGER.info("got country data");
        if (this.trustRegion != null) {
            model.addAttribute("trInfo", this.trustRegion);
        } else {
            model.addAttribute("trInfo", null);
        }
        return "TrustRegionDetail";
    }

    /**
     * process add new trust region.
     * @param model stored data to pass
     * @return string
     * @throws IOException throws
     * @throws SystemException throws
     */
    @RequestMapping(value = "/AddTrustRegion", method = RequestMethod.GET)
    public final String addTrustRegion(final Model model) throws IOException,
            SystemException {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] {"Spring-Module.xml"});
        CountryServiceImpl coService = context.getBean("countryServiceImpl",
                CountryServiceImpl.class);
        List<Country> listCountry = coService.listCountry();
        model.addAttribute("listCountry", listCountry);

        //pass null for not have In-active button
        model.addAttribute("inActiveBtn", null);

        //set isUpdate == false to insert new region later
        this.isUpdate = false;
        return "TrustRegionDetail";
    }

    /**
     * process to save data, update or add.
     * @param request input data
     * @return string
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public @ResponseBody final String saveRegion(
            final HttpServletRequest request) {
        String countryName = request.getParameter("countryName").trim();
        String regionName = request.getParameter("regionName").trim();
        String description = request.getParameter("description").trim();
        // get data from database
        ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] {"Spring-Module.xml"});
        TrustRegionServiceImpl trService = context.getBean(
                "trustRegionServiceImpl", TrustRegionServiceImpl.class);
        CountryServiceImpl coService = context.getBean("countryServiceImpl",
                CountryServiceImpl.class);
        String msg = "";
        try {
            // check if regionName is existed,
            int newRegionID = trService.getRegionIdByName(regionName);

            // if it existed and this process is add - then return a error
            if (newRegionID > 0 && !isUpdate) {
                return "{\"result\": \"2\",\"message\": "
                       + "\"This trust region was existed, "
                       + "please choose another name!\"}";
            }
            // get countryID to save
            int countryID = coService.getCountryIdByName(countryName);

            // check if process is update or not
            if (!isUpdate) {

                // process when is not update, insert new region
                TrustRegion tr = new TrustRegion(countryID, regionName,
                        description, "Yes");
                boolean rs = trService.addTrustRegion(tr);
                if (rs) {
                    msg = "{\"result\": \"1\",\"message\":"
                          + " \"Added new trust region successful!\"}";
                } else {
                    msg = "{\"result\": \"2\",\"message\":"
                          + " \"Add new trust region failed!\"}";
                }
            } else {

                // process when is update, update region
                // get regionID from old regionName
                int oldRegionID = this.trustRegion.getId();

                // check oldRegionID and newRegionID, if newRegionID was existed
                // and different oldRegionID - then return error
                if ((oldRegionID != newRegionID) && (newRegionID > 0)) {
                    return "{\"result\": \"2\",\"message\": "
                           + "\"This trust region was existed,"
                           + " please choose another name!\"}";
                }
                TrustRegion tr = new TrustRegion(countryID, regionName,
                        description, "Yes");

                // set an id for update sql
                tr.setId(oldRegionID);
                boolean rs = trService.amendTrustRegion(tr);
                if (rs) {
                    msg = "{\"result\": \"1\",\"message\":"
                          + " \"Amend trust region successful!\"}";
                } else {
                    msg = "{\"result\": \"2\",\"message\":"
                          + " \"Amend trust region failed!\"}";
                }
            }
        } catch (SystemException e) {
            e.printStackTrace();
        }
        return msg;
    }

    /**
     * amend trust region to active.
     * @param request in parameter
     * @return string
     * @throws IOException throws i/o exception
     */
    @RequestMapping(value = "/makeActiveRegion", method = RequestMethod.POST)
    public @ResponseBody final String makeActiveRegion(
            final HttpServletRequest request) throws IOException {
        String countryName = request.getParameter("countryName").trim();
        String regionName = request.getParameter("regionName").trim();
        String description = request.getParameter("description").trim();
        if (countryName == null || regionName == null || description == null) {
            return "{\"result\": \"2\",\"message\": \"Active failed!\"}";
        } else {
            if (countryName.isEmpty() || regionName.isEmpty()
                    || description.isEmpty()) {
                return "{\"result\": \"2\",\"message\": \"Active failed!\"}";
            } else {

                // create object to pass data
                trustRegion = new TrustRegion();
                trustRegion.setCountryName(countryName);
                trustRegion.setName(regionName);
                trustRegion.setDescription(description);
            }
        }

        // get regionID
        ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] {"Spring-Module.xml"});
        TrustRegionServiceImpl trService = context.getBean(
                "trustRegionServiceImpl", TrustRegionServiceImpl.class);
        int regionID = -1;
        String msg = "";
        try {
            regionID = trService.getRegionIdByName(regionName);

            // make region active, pass 1 for active this region
            if (trService.changTrustRegionStatus(regionID, 1)) {

                // set this validated trustRegionID to this.trustRegion for
                // amend later
                this.trustRegion.setId(regionID);

                // return message
                msg = "{\"result\": \"1\",\"message\": \"Active successful!\"}";
            } else {
                msg = "{\"result\": \"2\",\"message\":"
                      + " \"Active failed! Trust Region Name is not valid\"}";
            }
        } catch (SystemException e) {
            e.printStackTrace();
            msg = "{\"result\": \"2\",\"message\": \"Active failed!\"}";
        }

        return msg;
    }

    /**
     * amend region to In-active.
     * @param request in parameter to get data
     * @return string ajax
     * @throws IOException throws i/o exception
     */
    @RequestMapping(value = "/amendInactive", method = RequestMethod.POST)
    public @ResponseBody final String amendInactive(
            final HttpServletRequest request) throws IOException {
        LOGGER.info("amend In-Active Region");
        String regionName = request.getParameter("regionName").trim();
        if (regionName == null) {
            return "{\"result\": \"2\",\"message\": \"In-active failed!\"}";
        } else {
            if (regionName.isEmpty()) {
                return "{\"result\": \"2\",\"message\": \"In-active failed!\"}";
            } else {
                System.out.println(regionName.trim());
            }
        }

        // get regionID
        ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] {"Spring-Module.xml"});
        TrustRegionServiceImpl trService = context.getBean(
                "trustRegionServiceImpl", TrustRegionServiceImpl.class);
        int regionID = -1;
        String msg = "";
        try {
            regionID = trService.getRegionIdByName(regionName);

            // make region active, pass 0 for in-active this region
            if (trService.changTrustRegionStatus(regionID, 0)) {
                msg = "{\"result\": \"1\",\"message\":"
                      + " \"In-active successful!\"}";
            } else {
                msg = "{\"result\": \"2\",\"message\":"
                    + " \"In-active failed!, Trust Region Name is not valid\"}";
            }
        } catch (SystemException e) {
            e.printStackTrace();
            msg = "{\"result\": \"2\",\"message\": \"In-active failed!\"}";
        }
        return msg;
    }
}
